/*
 * Copyright (c) 2018-2999 九五云信息科技有限公司 All rights reserved.
 *
 * https://www.gz-yami.com/
 *
 * 未经允许，不可做商业用途！
 *
 * 版权所有，侵权必究！
 */

package com.yami.shop.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.bean.app.param.UserRegisterParam;
import com.yami.shop.bean.event.UserDataEvent;
import com.yami.shop.bean.model.User;
import com.yami.shop.bean.param.*;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.common.util.RedisUtil;
import com.yami.shop.common.util.*;
import com.yami.shop.dao.OrderMapper;
import com.yami.shop.dao.UserExtensionMapper;
import com.yami.shop.dao.UserMapper;
import com.yami.shop.service.OrderRefundService;
import com.yami.shop.service.OrderService;
import com.yami.shop.service.UserExtensionService;
import com.yami.shop.service.UserService;
import lombok.AllArgsConstructor;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @author lgh on 2018/09/11.
 */
@Service
@AllArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    private final UserMapper userMapper;
    private final UserExtensionService userExtensionService;
    private final ApplicationEventPublisher eventPublisher;




    @Override
    public User getUserByUserId(String userId) {
        return userMapper.selectById(userId);
    }

    @Override
    public void setUserLevelBylevelId(Integer level, Integer levelType) {
        userMapper.setUserLevelBylevelId(level, levelType);
        userExtensionService.setUserLevelBylevelId(level, levelType);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void setUserLevelByGrowth(Integer level, Integer minNeedGrowth, Integer maxNeedGrowth, Integer levelType) {
        userMapper.setMaxUserLevelBylevelId(level,minNeedGrowth ,maxNeedGrowth,levelType);
        userExtensionService.setMaxUserLevelByLevelId(level,minNeedGrowth ,maxNeedGrowth,levelType);
    }


    /**
     * 看看有没有校验验证码成功的标识
     * @param userRegisterParam
     * @param checkRegisterSmsFlag
     */
    @Override
    public void validate(UserRegisterParam userRegisterParam, String checkRegisterSmsFlag) {
        if (StrUtil.isBlank(userRegisterParam.getCheckRegisterSmsFlag())) {
            // 验证码已过期，请重新发送验证码校验
            throw new YamiShopBindException("yami.verification.expire");
        } else {
            String checkRegisterSmsFlagMobile = RedisUtil.get(checkRegisterSmsFlag);
            if (!Objects.equals(checkRegisterSmsFlagMobile, userRegisterParam.getMobile())) {
                // 验证码已过期，请重新发送验证码校验
                throw new YamiShopBindException("yami.verification.expire");
            }
        }
    }

    @Override
    public User getUserDetail(String userId) {
        return userMapper.getUserDetail(userId);
    }

    @Override
    public IPage<User> getUserPage(PageParam<User> page, User user) {
        return  userMapper.getUserPage(page,user);
    }

    @Override
    public Map<String, User> getUserListByUserNumbers(Set<String> keySet) {
        if (keySet.size() == 0){
            return new HashMap<>();
        }
        List<User> userList = userMapper.getUserListByUserNumbers(keySet);
        Map<String, User> userMap = userList.stream().collect(Collectors.toMap(User::getUserId,user -> user));
        return userMap;
    }

    @Override
    public CustomerRespParam countUserByParam(CustomerReqParam param) {
        CustomerRespParam respParam = new CustomerRespParam();
        Date endTime = param.getEndTime();
        Date startTime = param.getStartTime();
        // 累积粉丝数
        param.setAppId(1);
//        param.setStartTime(null);
        param.setDateTime(endTime);
        if (Objects.isNull(param.getShopId())) {
            param.setMember(1);
            // 累计应该没有时间
            param.setStartTime(null);
            param.setEndTime(null);
            param.setDateTime(null);
            respParam.setFashNum(userMapper.countUserByParam(param));
            param.setDateTime(startTime);
            respParam.setPreFashNum(userMapper.countUserByParam(param));
            respParam.setFashNumRate(divRate(respParam.getPreFashNum(),respParam.getFashNum(),4));
        }

        // 累积会员数
        param.setDateTime(null);
        param.setMember(null);
        respParam.setMember( userMapper.countMemberByParam(param));
        param.setDateTime(endTime);
        respParam.setPreMember( userMapper.countMemberByParam(param));
        respParam.setMemberRate(divRate(respParam.getMember()-respParam.getPreMember(),respParam.getMember(),4));

        return respParam;
    }

    @Override
    public IPage<UserManagerParam> getUserInfoPage(PageParam<User> page, UserManagerReqParam user) {
        // user基本信息 积分 当前余额  累计金额
        Page<UserManagerParam> pages = new Page<>();
        pages.setCurrent(page.getCurrent());
        pages.setSize(page.getSize());
        List<UserManagerParam> list = userMapper.getUserPageByParam(new PageAdapter(page),user);
        pages.setRecords(list);
        Integer total = userMapper.countGetUserPageByParam(new PageAdapter(page), user);
        pages.setTotal(total);
        return pages;
    }

    @Override
    public IPage<UserManagerParam> getUserInfoPage(Page<User> page, UserManagerReqParam user) {
        // user基本信息 积分 当前余额  累计金额
        Page<UserManagerParam> pages = new Page<>();
        pages.setSize(page.getSize());
        pages.setCurrent(page.getCurrent());
        List<UserManagerParam> list = userMapper.getUserPageByParam(new PageAdapter(page),user);
        pages.setRecords(list);
        return pages;
    }

    @Override
    public UserManagerParam getuserInfo(String userId) {
        UserManagerParam param = userMapper.getuserInfo(userId);
        param.setCurrentScore(param.getScore());
        eventPublisher.publishEvent( new UserDataEvent(param));
        return param;
    }


    private Double divRate(Integer a, Integer b,Integer scale) {
        if (Objects.isNull(b) || b == 0 || Objects.isNull(a)) {
            return 0.0;
        }
        return Arith.div(a,b,scale);
    }
}
